Coverage Report

Created: 2024-12-19 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
D:\a\tools.proto\tools.proto\compiler\src\gen\template\parse_tree.rs
Line
Count
Source
1
// Copyright (c) 2024, BlockProject 3D
2
//
3
// All rights reserved.
4
//
5
// Redistribution and use in source and binary forms, with or without modification,
6
// are permitted provided that the following conditions are met:
7
//
8
//     * Redistributions of source code must retain the above copyright notice,
9
//       this list of conditions and the following disclaimer.
10
//     * Redistributions in binary form must reproduce the above copyright notice,
11
//       this list of conditions and the following disclaimer in the documentation
12
//       and/or other materials provided with the distribution.
13
//     * Neither the name of BlockProject 3D nor the names of its contributors
14
//       may be used to endorse or promote products derived from this software
15
//       without specific prior written permission.
16
//
17
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29
use crate::gen::template::functions::FunctionMap;
30
use crate::gen::template::Error;
31
use std::borrow::Cow;
32
33
#[derive(Clone, Debug)]
34
pub struct Variable<'a> {
35
    pub name: &'a str,
36
    pub function: Option<fn(&str) -> Cow<str>>,
37
}
38
39
#[derive(Clone, Debug)]
40
pub enum Component<'a> {
41
    Constant(&'a str),
42
    Variable(Variable<'a>),
43
    NewLine,
44
}
45
46
impl<'a> Component<'a> {
47
16.7k
    pub fn parse_variable(function_map: &FunctionMap, variable: &'a str) -> Result<Component<'a>, Error> {
48
16.7k
        match variable.find(":") {
49
16.5k
            None => Ok(Component::Variable(Variable {
50
16.5k
                name: variable,
51
16.5k
                function: None,
52
16.5k
            })),
53
218
            Some(id) => {
54
218
                let name = &variable[..id];
55
218
                let function_name = &variable[id + 1..];
56
218
                let function =
57
218
                    function_map.get(function_name).ok_or_else(|| 
Error::FunctionNotFound(function_name.into())0
)
?0
;
58
218
                Ok(Component::Variable(Variable {
59
218
                    name,
60
218
                    function: Some(function),
61
218
                }))
62
            }
63
        }
64
16.7k
    }
65
}
66
67
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
68
pub enum FragmentMode {
69
    Inline,
70
    Default,
71
}
72
73
impl FragmentMode {
74
129
    pub fn from_str(name: &str) -> Option<FragmentMode> {
75
129
        match name {
76
129
            "inline" => Some(FragmentMode::Inline),
77
0
            "Default" => Some(FragmentMode::Default),
78
0
            _ => None,
79
        }
80
129
    }
81
}
82
83
#[derive(Clone, Debug)]
84
pub struct Fragment<'a> {
85
    pub(crate) name: &'a str,
86
    pub(crate) content: Vec<Component<'a>>,
87
    pub(crate) mode: FragmentMode,
88
}
89
90
pub struct Token<'a> {
91
    start: usize,
92
    end: usize,
93
    data: &'a [u8],
94
}
95
96
impl<'a> Token<'a> {
97
21.5k
    pub fn new(data: &'a [u8]) -> Self {
98
21.5k
        Self { data, start: 0, end: 0 }
99
21.5k
    }
100
101
817k
    pub fn has_next(&self) -> bool {
102
817k
        self.end < self.data.len()
103
817k
    }
104
105
1.57M
    pub fn cur(&self) -> u8 {
106
1.57M
        self.data[self.end]
107
1.57M
    }
108
109
44.6k
    pub fn next(&self) -> Option<u8> {
110
44.6k
        if self.end + 1 < self.data.len() {
  Branch (110:12): [True: 42.2k, False: 2.22k]
  Branch (110:12): [True: 179, False: 1]
111
42.4k
            Some(self.data[self.end + 1])
112
        } else {
113
2.22k
            None
114
        }
115
44.6k
    }
116
117
66.1k
    pub fn pop(&mut self) -> Result<Option<&'a str>, Error> {
118
66.1k
        let start = self.start;
119
66.1k
        let end = self.end;
120
66.1k
        self.start = end + 1;
121
66.1k
        self.end = end;
122
66.1k
        if end > start && 
end - start > 053.0k
{
  Branch (122:12): [True: 52.7k, False: 13.0k]
  Branch (122:27): [True: 52.7k, False: 0]
  Branch (122:12): [True: 243, False: 78]
  Branch (122:27): [True: 243, False: 0]
123
53.0k
            let data = std::str::from_utf8(&self.data[start..end]).map_err(|_| 
Error::InvalidUTF80
)
?0
;
124
53.0k
            Ok(Some(data))
125
        } else {
126
13.1k
            Ok(None)
127
        }
128
66.1k
    }
129
130
807k
    pub fn inc(&mut self) {
131
807k
        self.end += 1;
132
807k
    }
133
}